﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.NetworkInformation;
using System.Threading;
using System.Xml.Linq;

namespace SimpleNetPinger
{
    public partial class Form1 : Form
    {
        
        //----PrivateVars---------------------//
        private string host = "ya.ru";
        private int timeToSleep = 1000;
        private int timeout = 2000;
        private bool Connection = NetworkInterface.GetIsNetworkAvailable();
        private int packageLost = 0;
        private int packageGet = 0;
        private double packageStat = 0.00;
        private int lostTotal = 0;
        private int gotTotal = 0;
        //------------------------------------//



        //----ApplicationPath-----------------//
        string path =
             System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location.Replace(
             System.IO.Path.GetFileName(System.Reflection.Assembly.GetEntryAssembly().Location), @"\snpsettings.xml")) + @"\snpsettings.xml";
        //-----------------------------------//

        delegate void dPinger();
        public delegate bool dConnChecker();
        public Form1()
        {
            InitializeComponent();
                        
        }



        //----Pinger---------------------------//
        void Pinger()
        {   

            Ping pingSender = new Ping();
            PingOptions options = new PingOptions();

            options.DontFragment = true;

            string data = "a";
            byte[] buffer = Encoding.ASCII.GetBytes(data);


            if (listBox1.Items.Count == 19)
            {
                listBox1.Items.Clear();
            }

            while (ConnChecker() == true)
            {
                //----Connection Information-------------------//
                if (lostTotal == 5)
                {
                    notifyIcon1.ShowBalloonTip(2000, "Connection info", "A lot of lost packeges", ToolTipIcon.Info);
                    this.gotTotal = 0;
                }
                else if (lostTotal == 3)
                {
                    gotTotal = 0;
                }
                else if (lostTotal == 15)
                {
                    notifyIcon1.ShowBalloonTip(2000, "Connection info", "Very bad connection!", ToolTipIcon.Info);
                    this.gotTotal = 0;
                }
                else if (gotTotal == 10)
                {
                    this.lostTotal = 0;
                }
                else if (lostTotal > 10 & gotTotal > 8)
                {
                    notifyIcon1.ShowBalloonTip(2000, "Connection info", "Connection up!", ToolTipIcon.Info);
                }
                //-------------------------------------------//


                PingReply reply = pingSender.Send(host, timeout, buffer, options);
                this.Invoke((MethodInvoker)delegate() {
                    if (reply.Status == IPStatus.Success)
                    {
                        this.listBox1.Items.Add(string.Format("\rAddress: {0}   ping: {1} ms   ttl: {2} \n",
                            reply.Address.ToString(),
                            reply.RoundtripTime.ToString(),
                            options.Ttl));


                        this.Invoke((MethodInvoker)delegate() { this.listBox1.SelectedIndex = listBox1.Items.Count - 1; });
                        this.packageGet += 1;
                        this.gotTotal += 1;
                    }
                    else
                    {
                        this.Invoke((MethodInvoker)delegate() { this.listBox1.Items.Add(string.Format("\rPackage lost... \n")); });
                        this.Invoke((MethodInvoker)delegate() { this.listBox1.SelectedIndex = listBox1.Items.Count - 1; });
                        this.packageLost += 1;
                        this.lostTotal += 1;
                        gotTotal = 0;
                    }
                });

                this.packageStat =Math.Round((packageLost / (Convert.ToDouble(packageGet) + Convert.ToDouble(packageLost)))*100,2);
                
                Thread.Sleep(timeToSleep);
                
                this.Invoke((MethodInvoker)delegate() { this.label7.Text = packageGet.ToString(); });
                this.Invoke((MethodInvoker)delegate() { this.label5.Text = packageLost.ToString(); });

                this.Invoke((MethodInvoker)delegate()
                {

                    try
                    {
                        this.progressBar1.Value = (packageGet / (packageLost + 1)) * 15;
                    }
                    catch
                    {
                        this.progressBar1.Value = 100;
                    }

                    if (packageStat > 52 && packageStat < 10)
                    {
                        this.notifyIcon1.Text = string.Format("SimpleNetPinger\n \nPackages Lost: {0} ({1}%)\nGood connection", packageLost, packageStat);
                    }
                    else if (packageStat > 10)
                    {
                        this.notifyIcon1.Text = string.Format("SimpleNetPinger\n \nPackages Lost: {0} ({1}%)\nNot stable connection!", packageLost, packageStat);
                    }
                    else if (packageStat < 2)
                    {
                        this.notifyIcon1.Text = string.Format("SimpleNetPinger\n \nPackages Lost: {0} ({1}%)\nStable connection", packageLost, packageStat);
                    }

                });



                this.Connection = NetworkInterface.GetIsNetworkAvailable();
            }
            ConnChecker();

        }
        //-------------------------------------------//




        //----ConnChecker----------------------------//
        public bool ConnChecker()
        {
            while (this.Connection == false)
            {
                this.Connection = NetworkInterface.GetIsNetworkAvailable();
                Thread.Sleep(3000);
            }
            return Connection;

        }
        //-------------------------------------------//



        //----FormElements---------------------------//
        private void Form1_Shown(object sender, EventArgs e)
        {
            this.WindowState = FormWindowState.Minimized;
            dConnChecker delConnChecker = new dConnChecker(ConnChecker);
            dPinger delPinger = new dPinger(Pinger);
            delPinger.BeginInvoke(null, null);
            delConnChecker.BeginInvoke(null, null);

        }

        private void button1_Click(object sender, EventArgs e)
        {
            this.panel1.Visible = false;
            this.host        = textBox2.Text;
            this.timeToSleep = int.Parse(textBox3.Text);
            this.timeout     = int.Parse(textBox4.Text);
            XElement saveSettings = new XElement("settings",
                   new XElement("host", textBox2.Text),
                   new XElement("timeToSleep", textBox3.Text),
                   new XElement("timeout", textBox4.Text));
            saveSettings.Save(path);

        }


        private void button2_Click(object sender, EventArgs e)
        {   
            Application.ExitThread();
            Application.Exit();
            
        }



        private void Form1_Deactivate(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)
            {
                this.ShowInTaskbar = false;
                notifyIcon1.Visible = true;
                Hide();
            }
        }

        private void notifyIcon1_MouseClick(object sender, MouseEventArgs e)
        {
            notifyIcon1.ContextMenuStrip = contextMenuStrip1;
            if (e.Button == MouseButtons.Left)
            {
                if (this.WindowState == FormWindowState.Minimized)
                {
                    Show();
                    this.WindowState = FormWindowState.Normal;
                    this.ShowInTaskbar = false;
                    notifyIcon1.Visible = true;
                }
                else if (this.WindowState == FormWindowState.Normal)
                {
                    Hide();
                    this.WindowState = FormWindowState.Minimized;
                    this.ShowInTaskbar = false;
                }
            }
        }

        private void stmExit_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void settingsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            panel1.Visible = true;

        }

        private void settingsToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            Show();
            this.panel1.Visible = true;
            this.WindowState = FormWindowState.Normal;

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            try
            {
                XDocument loadSettings = XDocument.Load(path);
                this.host = textBox2.Text = loadSettings.Document.Element("settings").Element("host").Value;
                this.timeToSleep = int.Parse(textBox3.Text = loadSettings.Document.Element("settings").Element("timeToSleep").Value);
                this.timeout = int.Parse(textBox4.Text = loadSettings.Document.Element("settings").Element("timeout").Value);
            }
            catch
            {
                XElement saveSettings = new XElement("settings",
                    new XElement("host", textBox2.Text = "ya.ru"),
                    new XElement("timeToSleep", textBox3.Text =Convert.ToString(1000)),
                    new XElement("timeout", textBox4.Text = Convert.ToString(2000)));
                saveSettings.Save(path);
            }
        }

        private void button2_Click_1(object sender, EventArgs e)
        {
            this.panel1.Visible = false;
        }

        private void simpleNetPingerToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Show();
            this.WindowState = FormWindowState.Normal;
        }
        //--------------------------------------------------------//
        

    }
}
